package com.xh.poster.core.impl;


import cn.hutool.core.util.StrUtil;
import com.xh.model.enums.PosterItemTypeEnum;
import com.xh.model.request.Items;
import com.xh.model.request.PreviewRequest;
import com.xh.poster.annotation.PosterBackground;
import com.xh.poster.annotation.PosterFontCss;
import com.xh.poster.annotation.PosterImageCss;
import com.xh.poster.core.abst.Poster;
import com.xh.poster.core.decorators.BackgroundDecorator;
import com.xh.poster.core.decorators.ImageDecorator;
import com.xh.poster.core.decorators.TextDecorator;
import com.xh.poster.font.DecorationEnum;
import com.xh.poster.font.FontFamilyEnum;
import com.xh.utils.FileUtil;
import com.xh.utils.ImageUtil;
import lombok.extern.slf4j.Slf4j;

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.lang.reflect.Field;
import java.util.Objects;

/**
 * @author yangXS
 * @Date 2020/11/21
 * @since 1.0
 */
@Slf4j
public class PosterDefaultImpl<E> implements PosterTemplate<E> {

    @Override
    public Poster annotationDrawPoster(E content) throws IllegalAccessException {
        // 反射获取所有属性
        Field[] fields = content.getClass().getDeclaredFields();

        // 第一个注解为背景配置
        if (fields.length > 0 && fields[0].getAnnotation(PosterBackground.class) != null) {

            // 最后需要执行绘制方法的类
            Poster finalDraw;
            PosterBackground ann = fields[0].getAnnotation(PosterBackground.class);

            fields[0].setAccessible(true);
            Object o = fields[0].get(content);
            if (o instanceof BufferedImage) {
                BufferedImage bg = (BufferedImage) o;
                finalDraw = new BackgroundDecorator().toBuilder()
                        .bgImage(bg)
                        .width(ann.width())
                        .height(ann.height())
                        .radius(ann.radius())
                        .radiusVal(ann.radiusVal())
                        .build();
            } else {
                throw new RuntimeException("背景注解标记的类型需要为BufferedImage, 并且不可为空.");
            }

            // 给背景绘制基本属性
            for (Field field : fields) {
                field.setAccessible(true);
                //获取属性值
                Object value = field.get(content);
                if (value instanceof String) {
                    String str = (String) value;
                    PosterFontCss posterFontCss = field.getAnnotation(PosterFontCss.class);
                    // 设置相对定位对象相关属性值
                    if (posterFontCss.anchorPoint().length() > 0 && posterFontCss.relativeItemFontSize() > 1) {
                        String val = "";
                        String flag = posterFontCss.anchorPoint();
                        for (Field tempField : fields) {
                            tempField.setAccessible(true);
                            Object valTemp = tempField.get(content);
                            if (valTemp instanceof String) {
                                PosterFontCss posterFontCssTemp = tempField.getAnnotation(PosterFontCss.class);
                                if (posterFontCssTemp.anchorPoint().length() > 0 && posterFontCssTemp.relativeItemFontSize() == 1 && posterFontCssTemp.anchorPoint().equals(flag)) {
                                    val = (String) valTemp;
                                    break;
                                }
                            }
                        }
                        finalDraw = drawTextImpl(finalDraw, str, val, posterFontCss);
                    } else {
                        finalDraw = drawTextImpl(finalDraw, str, null, posterFontCss);
                    }
                } else if (value instanceof BufferedImage) {
                    BufferedImage image = (BufferedImage) value;
                    PosterImageCss posterImageCss = field.getAnnotation(PosterImageCss.class);
                    finalDraw = drawImageImpl(finalDraw, image, posterImageCss);
                }

            }
            return finalDraw;
        } else {
            throw new RuntimeException("绘制字段为空,或者第一个属性不是背景,并且没有标记背景注解");
        }

    }

    @Override
    public Poster paramsDrawPoster(PreviewRequest request) {
        // 最后需要执行绘制方法的类
        Poster finalDraw = null;
        try {
            // 绘制背景图
            finalDraw = this.drawBgImage(request);
            // 绘制内容
            finalDraw = this.drawContext(request, finalDraw);

        } catch (Exception e) {
            log.error("", e);
        }
        return finalDraw;
    }

    /**
     * 绘制海报内容
     */
    private Poster drawContext(PreviewRequest request, Poster finalDraw) throws IOException {
        for (Items item : request.getItems()) {
            // 绘制文本
            if (PosterItemTypeEnum.TEXT.getType().equals(item.getT())) {
                finalDraw = new TextDecorator(finalDraw).toBuilder()
                        .positionX(item.getX())
                        .positionY(item.getY())
                        .fontSize(item.getS())
                        .canNewLine(true)
                        .width(item.getW())
                        .height(item.getH())
                        .content(item.getV())
                        .center(false)
                        .color(Color.decode(item.getC()))
                        .newLineLimit(10)
                        .decorationEnum(DecorationEnum.NONE)
                        .fontFamilyEnum(FontFamilyEnum.PING_FANG_SC_MEDIUM)
//                        .relativeItemContent(relativeText)
//                        .relativeItemFontSize(ann.relativeItemFontSize())
//                        .relativeItemX(ann.relativeItemX())
                        .build();
            }
            // 绘制图片
            if (PosterItemTypeEnum.IMAGE.getType().equals(item.getT())) {
                finalDraw = new ImageDecorator(finalDraw).toBuilder()
                        .positionX(item.getX())
                        .positionY(item.getY())
                        .width(item.getW())
                        .height(item.getH())
                        .circle(false)
                        .image(ImageIO.read(Objects.requireNonNull(FileUtil.getFileInputStream(item.getV()))))
                        .radius(false)
                        .radiusVal(0)
                        .build();
            }
            // 绘制二维码
            if (PosterItemTypeEnum.QR_CODE.getType().equals(item.getT())) {
                finalDraw = new ImageDecorator(finalDraw).toBuilder()
                        .positionX(item.getX())
                        .positionY(item.getY())
                        .width(item.getW())
                        .height(item.getH())
                        .circle(false)
                        .image(ImageIO.read(Objects.requireNonNull(FileUtil.getFileInputStream(item.getV()))))
                        .radius(false)
                        .radiusVal(0)
                        .build();
            }
            // 绘制头像
            if (PosterItemTypeEnum.AVATAR.getType().equals(item.getT())) {
                finalDraw = new ImageDecorator(finalDraw).toBuilder()
                        .positionX(item.getX())
                        .positionY(item.getY())
                        .width(item.getW())
                        .height(item.getH())
                        .circle(true)
                        .image(ImageIO.read(Objects.requireNonNull(FileUtil.getFileInputStream(item.getV()))))
                        .radius(false)
                        .radiusVal(0)
                        .build();
            }
        }
        return finalDraw;
    }

    /**
     * 绘制背景图片
     */
    private Poster drawBgImage(PreviewRequest request) throws IOException {
        BufferedImage bgBufferedImage;
        if (StrUtil.isEmpty(request.getBgUrl())) {
            // 生成白底背景图
            bgBufferedImage = ImageUtil.createBackgroundImg(request.getW(), request.getH());
        } else {
            // 使用上传的背景图
            bgBufferedImage = ImageIO.read(Objects.requireNonNull(FileUtil.getFileInputStream(request.getBgUrl())));
        }
        // 构建背景图
        return new BackgroundDecorator().toBuilder()
                .bgImage(bgBufferedImage)
                .width(request.getW())
                .height(request.getH())
                .build();
    }

    /**
     * 绘制文本装饰器
     *
     * @param base 基础图片
     * @param text 要绘制的文本
     * @return poster
     */
    protected Poster drawTextImpl(Poster base, String text, String relativeText, PosterFontCss ann) {

        if (ann == null) {
            return base;
        }

        return new TextDecorator(base).toBuilder()
                .positionX(ann.position()[0])
                .positionY(ann.position()[1])
                .fontSize(ann.size())
                .canNewLine(ann.canNewLine()[0] == 1)
                .width(ann.canNewLine()[1])
                .newLineLimit(ann.canNewLine()[2])
                .color(new Color(ann.color()[0], ann.color()[1], ann.color()[2]))
                .content(text)
                .center(ann.center())
                .decorationEnum(ann.decoration())
                .fontFamilyEnum(ann.fontFamily())
                .relativeItemContent(relativeText)
                .relativeItemFontSize(ann.relativeItemFontSize())
                .relativeItemX(ann.relativeItemX())
                .build();
    }

    /**
     * 绘制图片装饰器
     *
     * @param base  基础图片
     * @param image 要绘制的图片
     * @return poster
     */
    protected Poster drawImageImpl(Poster base, BufferedImage image, PosterImageCss ann) {

        if (ann == null) {
            return base;
        }

        return new ImageDecorator(base).toBuilder()
                .positionX(ann.position()[0])
                .positionY(ann.position()[1])
                .width(ann.width())
                .height(ann.height())
                .circle(ann.circle())
                .image(image)
                .radius(ann.radius())
                .radiusVal(ann.radiusVal())
                .build();
    }


}
